/**
 * @file game.h
 * @brief Game class definition
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 3 of the License.
 *
 * @author VestniK (Sergey N.Vidyuk) sir.vestnik@gmail.com
 * @date 16 Oct 2008
 */
#ifndef _Game_H_
#define _Game_H_

#include <QtCore/QObject>
#include <QtCore/QtGlobal>
#include <QtCore/QList>
#include <QtCore/QMap>

#include "defaults.h"
#include "tile.h"
#include "tileset.h"
#include "wall.h"

namespace mjn {

   class ServerPlayer;

   /** @brief Mahjong game logick implemintation
    *
    * @todo document this class!!!
    */
   class Game: public QObject
   {
      Q_OBJECT
      public:
         /** @brief Internal game mState
          *
          * @sa getState
          * @sa mState
          */
         enum GameState {WaitingForPlayers,ReadyToStart,Started};

         Game();
         virtual ~Game() {};

         /// Returns current round prevailing wind
         WindType wind() const {return mWind;};
         /** @brief Sets prevailing wind.
          *
          * This function created for tests. All changes of the game prevailing
          * wind are provided automatically and should never be made manually!
          * @deprecated
          */
         void setWind(WindType wind) {mWind = wind;};
         /// Checks if no more game slots avaluable;
         bool noSlots() const;
         /// Returns game current state
         GameState state() const {return mState;};
         /// Returns game wall
         Wall &wall() {return mWall;};
         /// Returns game tile set
         const TileSet &tileSet() const {return mTileSet;};
         /// Returns a list of currently connected players.
         const QList<ServerPlayer *> &players() const {return mPlayers;}
         /// Request to add new player.
         ServerPlayer *addNewPlayer();
         /// Ends current turn and starts a new one.
         void nextTurn(TileID discarded_tile);
         /// Takes current discarded tile.
         TileID takeDiscardedTile();
         /// Start new game.
         bool start();

      signals:
         /**
          * This signal is emmited each time one of players discards a tile to
          * end his turn.
          *
          * @param discardedTile tile that was discurded by the player.
          */
         void tileDiscarded(mjn::TileID discardedTile);
         /**
          * This signal is emitted if round is failed (the wall contains only
          * 14 tiles and nobody win)
          */
         void roundFailed();
      private:
         /// Tiles set for this game
         TileSet mTileSet;
         WindType mWind;
         QList<ServerPlayer *> mPlayers;
         Wall mWall;
         GameState mState;
         TileID mDiscardedTile;
         /** @brief Current player.
          *
          * The player which should make his turn right now. Player is identified
          * by his wind. It's done since the mahjong rules describes the player
          * turns sequence in terms of winds.
          */
         WindType currentPlayer;

         /// Start new Prevailing Wind Set.
         void startSet( WindType prevailingWind );
         /// Start new round.
         void startRound();
   };

} // namespace mjn

#endif
